﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace SharePointOfView.SPReporting
{
    /// <summary>
    /// Class that represents a Report for SharePoint
    /// </summary>
    public class Report
    {
        #region Properties
        public string Name { get; set; }
        public int Versions { get; set; }
        public string Source { get; set; }
        public string Xslt { get; set; }
        public Globals.ChartSeries ChartType { get; set; }
        public Dictionary<DateTime, string> Xml { get; set; }
        #endregion 

        #region Private variables
        private readonly string reportsModelsDocLibUrl;
        private readonly string reportsDocLibUrl;
        #endregion

        /// <summary>
        /// Initialize a new report
        /// </summary>
        /// <param name="reportId">Report's id</param>
        public Report(int reportId)
        {
            try
            {
                reportsModelsDocLibUrl = Utilities.GetResourceString("SoVSPReportingLists_ReportingModelsList_Url");
                reportsDocLibUrl = Utilities.GetResourceString("SoVSPReportingLists_ReportingReportsList_Url");

                SPDocumentLibrary modelsLib = SPContext.Current.Web.GetList(SPUrlUtility.CombineUrl(SPContext.Current.Web.ServerRelativeUrl, reportsModelsDocLibUrl)) as SPDocumentLibrary;

                if (modelsLib != null)
                {
                    SPListItem model = modelsLib.Items.GetItemById(reportId);
                    if (model != null)
                    {
                        Name = (string)model["Title"];
                        Versions = Convert.ToInt32((double) model["VersionsRange"]);
                        Source = (string) model["ReportSource"];
                        Xslt = SPContext.Current.Web.GetFileAsString(model.File.Url);
                        Xml = GetSourceXml();
                    }
                }
            }
            catch (Exception ex)
            {
                Name = ex.Message + "\r\n" + ex.StackTrace;
            }
        }

        /// <summary>
        /// Retrieve Xml Source of report
        /// </summary>
        /// <returns></returns>
        private Dictionary<DateTime, string> GetSourceXml()
        {
            Dictionary<DateTime, string> sourceXml = new Dictionary<DateTime, string>(Versions);

            try
            {
                string sourceUrl = SPUrlUtility.CombineUrl(reportsDocLibUrl, Source);

                if (Versions == 1)
                {
                    sourceXml.Add(DateTime.Now, SPContext.Current.Web.GetFileAsString(sourceUrl));
                }
                else
                {
                    SPFile file = SPContext.Current.Web.GetFile(sourceUrl);
                    int lastVersion = file.Versions.Count - Versions;
                    if (lastVersion < 0) lastVersion = 0;
                    for (int i = file.Versions.Count - 1; i >= lastVersion; i--)
                    {
                        // Get File Version
                        SPFileVersion fileVersion = file.Versions[i];
                        byte[] content = fileVersion.OpenBinary();
                        // Add new content for the version creation date
                        sourceXml.Add(fileVersion.Created, Encoding.Default.GetString(content));
                    }
                }
            }
            catch (Exception ex)
            {
                sourceXml.Add(DateTime.Now, string.Format("<Error>{0}</Error>", HttpUtility.HtmlEncode(ex.Message)));
            }

            return sourceXml;
        }

        /// <summary>
        /// Cache Key for report's model
        /// </summary>
        /// <param name="Id">Report's id</param>
        /// <returns></returns>
        private static string CacheyKey(int Id)
        {
            return "SPReporting_Report_" + Id;
        }

        /// <summary>
        /// Cache object
        /// </summary>
        private class CacheObject
        {
            public DateTime LastModified { get; set; }
            public string Content { get; set; }
        }
    }
}